﻿using System.Linq.Dynamic.Core;
using System.Net;
using System.Net.Http;
using System.Net.Http.Json;
using Smartstore.Core.Catalog.Attributes;
using Smartstore.Core.Checkout.GiftCards;
using Smartstore.Core.Common;
using Smartstore.Core.Data;
using Smartstore.Core.Security;
using Smartstore.Core.Seo;
using Smartstore.Core.Stores;
using Smartstore.Scheduling;


namespace Smartstore.Core.Catalog.Products
{
    /// <summary>
    /// 同步创达医疗器械系统器械
    /// </summary>
    public partial class SyncProductTask : ITask
    {
        private readonly SmartDbContext _db;
        private readonly IHttpClientFactory _httpClientFactory;
        private readonly IUrlService _urlService;
        private readonly IStoreMappingService _storeMappingService;
        //private readonly Lazy<IProductAttributeService> _productAttributeService;
        private readonly IAclService _aclService;

        public SyncProductTask(SmartDbContext db, 
            IHttpClientFactory httpClientFactory,
            IUrlService urlService,
            IStoreMappingService storeMappingService,
            //Lazy<IProductAttributeService> productAttributeService,
            IAclService aclService
            )
        {
            _db = db;
            _httpClientFactory = httpClientFactory;
            _urlService = urlService;
            _storeMappingService = storeMappingService;
            //_productAttributeService = productAttributeService;
            _aclService = aclService;
        }

        public async Task Run(TaskExecutionContext ctx, CancellationToken cancelToken = default)
        {
            List<Store> stores = _db.Stores.Where(m => m.SyncYLQXEnabled && !string.IsNullOrEmpty(m.SyncYLQXProductUrl)).ToList();
            if (stores.Count > 0)
            {
                // 商品模板
                var productTemplate = _db.ProductTemplates.First(x => x.ViewPath == "Product");
                var manufacturerTemplate = _db.ManufacturerTemplates.First();
                // 规格
                var spec = _db.ProductAttributes.FirstOrDefault(m => m.Alias == "spec");
                // 型号
                var model = _db.ProductAttributes.FirstOrDefault(m => m.Alias == "model");

                // 税类型
                var taxCategory = _db.TaxCategories.First();
                // 货运方式
                var firstDeliveryTime = _db.DeliveryTimes.First();
                HttpClient client = _httpClientFactory.CreateClient();
                client.Timeout = TimeSpan.FromSeconds(30);
                foreach (Store store in stores)
                {
                    // 制造商
                    var manufacturers = _db.Manufacturers.ApplyStoreFilter(store.Id).ToList();
                    // 外部关联
                    var originals = _db.OriginalMappings.Where(m => m.StoreId == store.Id && m.EntityName == nameof(Product)).ToList();
                    var formContent = new FormUrlEncodedContent(new KeyValuePair<string, string>[]
                    {
                        new("pnum", "1"),
                        new("psize", (store.SyncYLQXPageSize > 0 ? store.SyncYLQXPageSize:10).ToString()),
                        new("lastId", store.SyncYLQXProductId.ToString())
                    });
                    var response = await client.PostAsync(store.SyncYLQXProductUrl, formContent);
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        var result = await response.Content.ReadFromJsonAsync<YLQXModel>();
                        if (result.r && result.code == 200)
                        {
                            foreach (var item in result.data.list)
                            {

                                // 按照名称、注册证号、生产厂家为唯一标识，相同则视为同一个商品的不同规格
                                Product newProduct = _db.Products.FirstOrDefault(m => m.Name == item.Name && m.Gtin == item.RegNo && m.Producer == item.Producer);
                                if (null == newProduct)
                                {
                                    #region 单位
                                    var quantityUnit = _db.QuantityUnits.FirstOrDefault(m => m.Name == item.UnitMin);
                                    if (null == quantityUnit)
                                    {
                                        quantityUnit = new QuantityUnit
                                        {
                                            Name = item.UnitMin,
                                            NamePlural = item.UnitMin,
                                            Description = null,
                                            DisplayLocale = null,
                                            DisplayOrder = 0,
                                            IsDefault = false,
                                        };
                                        _db.QuantityUnits.Add(quantityUnit);
                                        await _db.SaveChangesAsync();
                                    }
                                    #endregion

                                    #region 新增器械
                                    newProduct = new Product
                                    {
                                        ProductTypeId = (int)ProductType.SimpleProduct,
                                        ParentGroupedProductId = 0,
                                        Visibility = (int)ProductVisibility.Full,
                                        Condition = (int)ProductCondition.New,
                                        Name = item.Name,
                                        ShortDescription = null,
                                        FullDescription = null,
                                        AdminComment = null,
                                        ProductTemplateId = productTemplate.Id,
                                        ShowOnHomePage = false,
                                        HomePageDisplayOrder = 0,
                                        MetaKeywords = null,
                                        MetaDescription = null,
                                        MetaTitle = null,
                                        AllowCustomerReviews = true,
                                        ApprovedRatingSum = 0,
                                        NotApprovedRatingSum = 0,
                                        ApprovedTotalReviews = 0,
                                        NotApprovedTotalReviews = 0,
                                        SubjectToAcl = false,
                                        LimitedToStores = true,
                                        LimitedToStoreId = store.Id,
                                        Sku = item.Sku,
                                        ManufacturerPartNumber = item.SCXKH,
                                        Gtin = item.RegNo,
                                        Producer = item.Producer,
                                        IsGiftCard = false,
                                        GiftCardTypeId = (int)GiftCardType.Virtual,
                                        RequireOtherProducts = false,
                                        RequiredProductIds = null,
                                        AutomaticallyAddRequiredProducts = false,
                                        IsDownload = false,
                                        UnlimitedDownloads = false,
                                        MaxNumberOfDownloads = 0,
                                        DownloadExpirationDays = null,
                                        DownloadActivationTypeId = (int)DownloadActivationType.WhenOrderIsPaid,
                                        HasSampleDownload = false,
                                        SampleDownloadId = null,
                                        HasUserAgreement = false,
                                        UserAgreementText = null,
                                        IsRecurring = false,
                                        RecurringCycleLength = 100,
                                        RecurringCyclePeriodId = (int)RecurringProductCyclePeriod.Days,
                                        RecurringTotalCycles = 10,
                                        IsShippingEnabled = true,
                                        IsFreeShipping = false,
                                        AdditionalShippingCharge = 0,
                                        IsTaxExempt = false,
                                        IsEsd = false,
                                        TaxCategoryId = taxCategory.Id,
                                        ManageInventoryMethodId = (int)ManageInventoryMethod.ManageStock,
                                        StockQuantity = (int)item.Available,
                                        DisplayStockAvailability = false,
                                        DisplayStockQuantity = false,
                                        MinStockQuantity = 0,
                                        LowStockActivityId = (int)LowStockActivity.Nothing,
                                        NotifyAdminForQuantityBelow = 0,
                                        BackorderModeId = (int)BackorderMode.NoBackorders,
                                        AllowBackInStockSubscriptions = false,
                                        OrderMinimumQuantity = 1,
                                        OrderMaximumQuantity = 50,
                                        QuantityStep = 1,
                                        QuantityControlType = QuantityControlType.Spinner,
                                        HideQuantityControl = false,
                                        AllowedQuantities = null,
                                        DisableBuyButton = false,
                                        DisableWishlistButton = false,
                                        AvailableForPreOrder = false,
                                        CallForPrice = false,
                                        Price = item.PriceWithTax,
                                        ComparePrice = 0,
                                        ProductCost = item.CostWithTax,
                                        SpecialPrice = null,
                                        SpecialPriceStartDateTimeUtc = null,
                                        SpecialPriceEndDateTimeUtc = null,
                                        CustomerEntersPrice = false,
                                        MinimumCustomerEnteredPrice = 0,
                                        MaximumCustomerEnteredPrice = 1000,
                                        HasTierPrices = false,
                                        LowestAttributeCombinationPrice = null,
                                        AttributeCombinationRequired = false,
                                        AttributeChoiceBehaviour = AttributeChoiceBehaviour.GrayOutUnavailable,
                                        Weight = 0,
                                        Length = 0,
                                        Width = 0,
                                        Height = 0,
                                        AvailableStartDateTimeUtc = null,
                                        AvailableEndDateTimeUtc = null,
                                        DisplayOrder = 0,
                                        Published = true,
                                        Deleted = false,
                                        IsSystemProduct = false,
                                        SystemName = null,
                                        CreatedOnUtc = DateTime.Now,
                                        UpdatedOnUtc = DateTime.Now,
                                        DeliveryTimeId = firstDeliveryTime.Id,
                                        QuantityUnitId = quantityUnit.Id,
                                        CustomsTariffNumber = null,
                                        CountryOfOriginId = null,
                                        BasePriceEnabled = false,
                                        BasePriceMeasureUnit = null,
                                        BasePriceAmount = null,
                                        BasePriceBaseAmount = null,
                                        BundleTitleText = null,
                                        BundlePerItemShipping = false,
                                        BundlePerItemPricing = false,
                                        BundlePerItemShoppingCart = false,
                                        MainPictureId = null,
                                        HasPreviewPicture = false,
                                        HasDiscountsApplied = false,
                                    };
                                    _db.Products.Add(newProduct);
                                    await _db.SaveChangesAsync();
                                    #endregion

                                    var attributeSelection = new ProductVariantAttributeSelection(string.Empty);

                                    if (string.IsNullOrEmpty(item.Spec))
                                    {
                                        var attribute = new ProductVariantAttribute
                                        {
                                            ProductId = newProduct.Id,
                                            ProductAttributeId = spec.Id,
                                            TextPrompt = null,
                                            CustomData = null,
                                            IsRequired = true,
                                            AttributeControlTypeId = (int)AttributeControlType.RadioList,
                                            DisplayOrder = 0
                                        };
                                        var attributeValue = new ProductVariantAttributeValue
                                        {
                                            ProductVariantAttributeId = attribute.Id,
                                            Name = item.Spec,
                                            Alias = null,
                                            MediaFileId = 0,
                                            Color = null,
                                            PriceAdjustment = 0,
                                            WeightAdjustment = 0,
                                            IsPreSelected = true,
                                            DisplayOrder = 0,
                                            ValueTypeId = (int)ProductVariantAttributeValueType.Simple,
                                            LinkedProductId = 0,
                                            Quantity = 1
                                        };
                                        attribute.ProductVariantAttributeValues.Add(attributeValue);
                                        newProduct.ProductVariantAttributes.Add(attribute);
                                        await _db.SaveChangesAsync();
                                        // 插入属性集合
                                        attributeSelection.AddAttributeValue(attribute.Id, attributeValue.Id);
                                    }

                                    if (string.IsNullOrEmpty(item.Model))
                                    {
                                        var attribute = new ProductVariantAttribute
                                        {
                                            ProductId = newProduct.Id,
                                            ProductAttributeId = model.Id,
                                            TextPrompt = null,
                                            CustomData = null,
                                            IsRequired = true,
                                            AttributeControlTypeId = (int)AttributeControlType.RadioList,
                                            DisplayOrder = 0
                                        };
                                        var attributeValue = new ProductVariantAttributeValue
                                        {
                                            ProductVariantAttributeId = attribute.Id,
                                            Name = item.Model,
                                            Alias = null,
                                            MediaFileId = 0,
                                            Color = null,
                                            PriceAdjustment = 0,
                                            WeightAdjustment = 0,
                                            IsPreSelected = true,
                                            DisplayOrder = 0,
                                            ValueTypeId = (int)ProductVariantAttributeValueType.Simple,
                                            LinkedProductId = 0,
                                            Quantity = 1
                                        };
                                        attribute.ProductVariantAttributeValues.Add(attributeValue);
                                        newProduct.ProductVariantAttributes.Add(attribute);
                                        await _db.SaveChangesAsync();
                                        // 插入属性集合
                                        attributeSelection.AddAttributeValue(attribute.Id, attributeValue.Id);
                                    }

                                    // 属性组合
                                    var attributeCombination = new ProductVariantAttributeCombination
                                    {
                                        ProductId = newProduct.Id,
                                        Sku = item.Sku,
                                        Gtin = item.RegNo,
                                        ManufacturerPartNumber = item.SCXKH,
                                        Price = item.PriceWithTax,
                                        Length = 0,
                                        Width = 0,
                                        Height = 0,
                                        BasePriceAmount = null,
                                        BasePriceBaseAmount = null,
                                        AssignedMediaFileIds = null,
                                        IsActive = true,
                                        DeliveryTimeId = null,
                                        QuantityUnitId = null,
                                        RawAttributes = attributeSelection.AsJson(),
                                        StockQuantity = (int)item.Available,
                                        AllowOutOfStockOrders = true
                                    };
                                    _db.ProductVariantAttributeCombinations.Add(attributeCombination);
                                    await _db.SaveChangesAsync();

                                    // url
                                    await _urlService.SaveSlugAsync(newProduct, item.Sku, newProduct.GetDisplayName(), true);
                                    // 限于仓库
                                    await _storeMappingService.ApplyStoreMappingsAsync(newProduct, [store.Id]);
                                }
                                else
                                {

                                }


                                var original = originals.FirstOrDefault(m => m.OriginalId == item.ID && m.EntityName == nameof(Product));
                                if (null != original)
                                {
                                    if (newProduct.Id != original.EntityId)
                                    {
                                        original.EntityId = newProduct.Id;
                                        _db.OriginalMappings.Update(original);
                                        await _db.SaveChangesAsync();
                                    }
                                }
                                else
                                {
                                    original = new OriginalMapping
                                    {
                                        EntityId = newProduct.Id,
                                        EntityName = nameof(Product),
                                        StoreId = store.Id,
                                        OriginalId = item.ID
                                    };
                                    _db.OriginalMappings.Add(original);
                                    await _db.SaveChangesAsync();
                                }

                                // 更新店铺最新执行记录
                                store.SyncYLQXProductId = item.ID;
                                await _db.SaveChangesAsync();
                                //Product newProduct = null;
                                //var original = originals.FirstOrDefault(m => m.OriginalId == item.ID);
                                //if (null != original)
                                //{
                                //    newProduct = _db.Products.FirstOrDefault(m => m.Id == original.EntityId);
                                //    if (null == newProduct)
                                //    {
                                //        _db.OriginalMappings.Remove(original);
                                //    }
                                //}
                                //if (null == newProduct)
                                //{
                                //    var quantityUnit = _db.QuantityUnits.FirstOrDefault(m => m.Name == item.UnitMin);
                                //    if (null == quantityUnit)
                                //    {
                                //        quantityUnit = new QuantityUnit
                                //        {
                                //            Name = item.UnitMin,
                                //            NamePlural = item.UnitMin,
                                //            Description = null,
                                //            DisplayLocale = null,
                                //            DisplayOrder = 0,
                                //            IsDefault = false,
                                //        };
                                //        _db.QuantityUnits.Add(quantityUnit);
                                //        await _db.SaveChangesAsync();
                                //    }

                                //    var manufacturer = manufacturers.FirstOrDefault(m => m.Name == item.Producer);
                                //    if (null == manufacturer)
                                //    {
                                //        manufacturer = new Manufacturer
                                //        {
                                //            Name = item.Producer,
                                //            Description = null,
                                //            BottomDescription = null,
                                //            ManufacturerTemplateId = manufacturerTemplate.Id,
                                //            MetaKeywords = null,
                                //            MetaDescription = null,
                                //            MetaTitle = null,
                                //            MediaFileId = null,
                                //            PageSize = null,
                                //            AllowCustomersToSelectPageSize = null,
                                //            PageSizeOptions = null,
                                //            LimitedToStores = true,
                                //            SubjectToAcl = false,
                                //            Published = true,
                                //            Deleted = false,
                                //            DisplayOrder = 0,
                                //            CreatedOnUtc = DateTime.Now,
                                //            UpdatedOnUtc = DateTime.Now,
                                //            HasDiscountsApplied = false
                                //        };
                                //        _db.Manufacturers.Add(manufacturer);
                                //        await _db.SaveChangesAsync();
                                //        await _storeMappingService.ApplyStoreMappingsAsync(manufacturer, [store.Id]);

                                //        // 新增的制造商增加到List，否则重复添加
                                //        manufacturers.Add(manufacturer);
                                //    }

                                //    newProduct = new Product
                                //    {
                                //        ProductTypeId = (int)ProductType.SimpleProduct,
                                //        ParentGroupedProductId = 0,
                                //        Visibility = (int)ProductVisibility.Full,
                                //        Condition = (int)ProductCondition.New,
                                //        Name = item.Name,
                                //        ShortDescription = null,
                                //        FullDescription = null,
                                //        AdminComment = null,
                                //        ProductTemplateId = productTemplate.Id,
                                //        ShowOnHomePage = false,
                                //        HomePageDisplayOrder = 0,
                                //        MetaKeywords = null,
                                //        MetaDescription = null,
                                //        MetaTitle = null,
                                //        AllowCustomerReviews = true,
                                //        ApprovedRatingSum = 0,
                                //        NotApprovedRatingSum = 0,
                                //        ApprovedTotalReviews = 0,
                                //        NotApprovedTotalReviews = 0,
                                //        SubjectToAcl = false,
                                //        LimitedToStores = true,
                                //        LimitedToStoreId = store.Id,
                                //        Sku = item.Sku,
                                //        ManufacturerPartNumber = item.SCXKH,
                                //        Gtin = item.RegNo,
                                //        Producer = item.Producer,
                                //        IsGiftCard = false,
                                //        GiftCardTypeId = (int)GiftCardType.Virtual,
                                //        RequireOtherProducts = false,
                                //        RequiredProductIds = null,
                                //        AutomaticallyAddRequiredProducts = false,
                                //        IsDownload = false,
                                //        UnlimitedDownloads = false,
                                //        MaxNumberOfDownloads = 0,
                                //        DownloadExpirationDays = null,
                                //        DownloadActivationTypeId = (int)DownloadActivationType.WhenOrderIsPaid,
                                //        HasSampleDownload = false,
                                //        SampleDownloadId = null,
                                //        HasUserAgreement = false,
                                //        UserAgreementText = null,
                                //        IsRecurring = false,
                                //        RecurringCycleLength = 100,
                                //        RecurringCyclePeriodId = (int)RecurringProductCyclePeriod.Days,
                                //        RecurringTotalCycles = 10,
                                //        IsShippingEnabled = true,
                                //        IsFreeShipping = false,
                                //        AdditionalShippingCharge = 0,
                                //        IsTaxExempt = false,
                                //        IsEsd = false,
                                //        TaxCategoryId = taxCategory.Id,
                                //        ManageInventoryMethodId = (int)ManageInventoryMethod.ManageStock,
                                //        StockQuantity = (int)item.Available,
                                //        DisplayStockAvailability = false,
                                //        DisplayStockQuantity = false,
                                //        MinStockQuantity = 0,
                                //        LowStockActivityId = (int)LowStockActivity.Nothing,
                                //        NotifyAdminForQuantityBelow = 0,
                                //        BackorderModeId = (int)BackorderMode.NoBackorders,
                                //        AllowBackInStockSubscriptions = false,
                                //        OrderMinimumQuantity = 1,
                                //        OrderMaximumQuantity = 50,
                                //        QuantityStep = 1,
                                //        QuantityControlType = QuantityControlType.Spinner,
                                //        HideQuantityControl = false,
                                //        AllowedQuantities = null,
                                //        DisableBuyButton = false,
                                //        DisableWishlistButton = false,
                                //        AvailableForPreOrder = false,
                                //        CallForPrice = false,
                                //        Price = item.PriceWithTax,
                                //        ComparePrice = 0,
                                //        ProductCost = item.CostWithTax,
                                //        SpecialPrice = null,
                                //        SpecialPriceStartDateTimeUtc = null,
                                //        SpecialPriceEndDateTimeUtc = null,
                                //        CustomerEntersPrice = false,
                                //        MinimumCustomerEnteredPrice = 0,
                                //        MaximumCustomerEnteredPrice = 1000,
                                //        HasTierPrices = false,
                                //        LowestAttributeCombinationPrice = null,
                                //        AttributeCombinationRequired = false,
                                //        AttributeChoiceBehaviour = AttributeChoiceBehaviour.GrayOutUnavailable,
                                //        Weight = 0,
                                //        Length = 0,
                                //        Width = 0,
                                //        Height = 0,
                                //        AvailableStartDateTimeUtc = null,
                                //        AvailableEndDateTimeUtc = null,
                                //        DisplayOrder = 0,
                                //        Published = true,
                                //        Deleted = false,
                                //        IsSystemProduct = false,
                                //        SystemName = null,
                                //        CreatedOnUtc = DateTime.Now,
                                //        UpdatedOnUtc = DateTime.Now,
                                //        DeliveryTimeId = firstDeliveryTime.Id,
                                //        QuantityUnitId = quantityUnit.Id,
                                //        CustomsTariffNumber = null,
                                //        CountryOfOriginId = null,
                                //        BasePriceEnabled = false,
                                //        BasePriceMeasureUnit = null,
                                //        BasePriceAmount = null,
                                //        BasePriceBaseAmount = null,
                                //        BundleTitleText = null,
                                //        BundlePerItemShipping = false,
                                //        BundlePerItemPricing = false,
                                //        BundlePerItemShoppingCart = false,
                                //        MainPictureId = null,
                                //        HasPreviewPicture = false,
                                //        HasDiscountsApplied = false,
                                //    };
                                //    _db.Products.Add(newProduct);
                                //    await _db.SaveChangesAsync();

                                //    original = new OriginalMapping
                                //    {
                                //        EntityId = newProduct.Id,
                                //        EntityName = nameof(Product),
                                //        StoreId = store.Id,
                                //        OriginalId = item.ID
                                //    };
                                //    _db.OriginalMappings.Add(original);
                                //    await _db.SaveChangesAsync();

                                //    newProduct.ProductManufacturers.Add(new ProductManufacturer
                                //    {
                                //        ManufacturerId = manufacturer.Id,
                                //        ProductId = newProduct.Id,
                                //        IsFeaturedProduct = false,
                                //        DisplayOrder = 0
                                //    });
                                //    await _db.SaveChangesAsync();
                                //}
                                //else
                                //{
                                //    newProduct.Name = item.Name;
                                //    newProduct.LimitedToStoreId = store.Id;
                                //    newProduct.Sku = item.Sku;
                                //    newProduct.ManufacturerPartNumber = item.SCXKH;
                                //    newProduct.Gtin = item.RegNo;
                                //    newProduct.Producer = item.Producer;
                                //    newProduct.StockQuantity = (int)item.Available;
                                //    newProduct.Price = item.PriceWithTax;
                                //    newProduct.ProductCost = item.CostWithTax;
                                //    _db.Products.Update(newProduct);
                                //    await _db.SaveChangesAsync();
                                //}

                                //await _urlService.SaveSlugAsync(newProduct, item.Sku, newProduct.GetDisplayName(), true);
                                //await _storeMappingService.ApplyStoreMappingsAsync(newProduct, [store.Id]);

                                //await _aclService.ApplyAclMappingsAsync(newProduct, model.SelectedCustomerRoleIds);

                            }
                        }
                    }
                }
            }
        }
    }
}
